home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagg_m.zip / MATH.SWG / 0073_Text Formula Parser.pas < prev    next >
Pascal/Delphi Source File  |  1994-08-24  |  46KB  |  1,609 lines

  1. {---------------------------------------------------------}
  2. {  Project : Text Formula Parser                          }
  3. {  Auteur  : G.W. van der Vegt                            }
  4. {---------------------------------------------------------}
  5. {  Datum .tijd  Revisie                                   }
  6. {  900530.1900  Creatie (function call/exits removed).    }
  7. {  900531.1900  Revisie (Boolean expressions).            }
  8. {  900104.2100  Revisie (HEAP Function Storage).          }
  9. {  910327.1345  External Real string vars (tfp_realstr)   }
  10. {               are corrected the same way as the parser  }
  11. {               corrects them before using TURBO's VAL.   }
  12. {  910829.1200  Support added for recursion with string   }
  13. {               variables so they may contain formula's   }
  14. {               now.                                      }
  15. {  940411.1300  Hyperbolic, reciproke & inverse           }
  16. {               goniometric functions added,              }
  17. {               Type of tfp_lnr changed to Byte.          }
  18. {               Bug fixed in tfp_check (tfp_lnr not always}
  19. {               initialized to 0)                         }
  20. {---------------------------------------------------------}
  21.  
  22. UNIT Tfp_02;
  23.  
  24. INTERFACE
  25.  
  26. CONST
  27.   tfp_true      = 1.0;                   {----REAL value for BOOLEAN TRUE     }
  28.   tfp_false     = 0.0;                   {----REAL value for BOOLEAN FALSE    }
  29.   tfp_maxparm   = 16;                    {----Maximum number of parameters    }
  30.   tfp_funclen   = 12;                    {----Maximum function name length    }
  31.  
  32. TYPE
  33.   tfp_fname     = STRING[tfp_funclen];   {----Function Name or Alias          }
  34.   tfp_ftype     = (tfp_noparm,           {----Function or Function()          }
  35.                    tfp_1real,                  {----Function(VAR r)                 }
  36.                    tfp_2real,                  {----Function(VAR r1,r2)             }
  37.                    tfp_nreal,                  {----Function(VAR r;n  INTEGER)      }
  38.                    tfp_realvar,            {----Real VAR                        }
  39.                    tfp_intvar,           {----Integer VAR                     }
  40.                    tfp_boolvar,                 {----Boolean VAR                     }
  41.                    tfp_strvar);                 {----String VAR (Formula)            }
  42.  
  43.   tfp_rarray    = ARRAY[0..tfp_maxparm-1] OF REAL;
  44.  
  45. FUNCTION Tfp_parse2real(s : STRING): REAL;
  46.  
  47. FUNCTION Tfp_parse2str(s : STRING;m,n : INTEGER) : STRING;
  48.  
  49. {---------------------------------------------------------}
  50. {----Interface to error functions for external addons     }
  51. {---------------------------------------------------------}
  52.  
  53. VAR
  54.   tfp_erpos,
  55.   tfp_ernr      : BYTE;
  56.  
  57. PROCEDURE Tfp_seternr(ernr : INTEGER);
  58.  
  59. FUNCTION  Tfp_errormsg(nr : INTEGER) : STRING;
  60.  
  61. {---------------------------------------------------------}
  62. {----Initialize & Expand internal parser datastructure    }
  63. {---------------------------------------------------------}
  64.  
  65. PROCEDURE Tfp_init  (no : WORD);
  66.  
  67. PROCEDURE Tfp_expand(no : WORD);
  68.  
  69. {---------------------------------------------------------}
  70. {----Keep first no function+vars of parser                }
  71. {---------------------------------------------------------}
  72.  
  73. PROCEDURE Tfp_keep  (no : WORD);
  74.  
  75. {---------------------------------------------------------}
  76. {----Number of functions+vars added to parser             }
  77. {---------------------------------------------------------}
  78.  
  79. FUNCTION  Tfp_noobj : WORD;
  80.  
  81. {---------------------------------------------------------}
  82. {----Adds own FUNCTION or VAR to the parser               }
  83. {    All FUNCTIONS & VARS must be compiled                }
  84. {    with the FAR switch on                               }
  85. {---------------------------------------------------------}
  86.  
  87. PROCEDURE Tfp_addobj(adres : POINTER;
  88.                      name  : tfp_fname;
  89.                      ftype : tfp_ftype);
  90.  
  91. {---------------------------------------------------------}
  92. {----Add Internal Function Packs                          }
  93. {---------------------------------------------------------}
  94.  
  95. PROCEDURE Tfp_addgonio;
  96. PROCEDURE Tfp_addlogic;
  97. PROCEDURE Tfp_addmath;
  98. PROCEDURE Tfp_addmisc;
  99. PROCEDURE Tfp_addall;
  100.  
  101. {---------------------------------------------------------}
  102.  
  103. IMPLEMENTATION
  104.  
  105. TYPE
  106.   tfp_parse_state = RECORD
  107.                       tfp_line     : STRING; {----Copy of string to Parse   }
  108.                       tfp_lp       : BYTE;   {----Parsing Pointer into Line }
  109.                       tfp_nextchar : CHAR;   {----Character at Lp Postion   }
  110.                      END;
  111.  
  112.   tfp_state_ptr   = ^tfp_parse_state;
  113.  
  114. CONST
  115.   tfp_maxreal     = +9.99999999e37;          {----Internal maxreal                }
  116.   tfp_maxlongint  = maxlongint-1;       {----Internal longint                }
  117.  
  118. VAR
  119.   maxfie      : INTEGER;                    {----max no of functions & vars      }
  120.   fiesiz      : INTEGER;                    {----current no of functions & vars  }
  121.   p           : tfp_state_ptr;          {----Top level formula               }
  122.  
  123. TYPE
  124.   tfp_fie_typ = RECORD
  125.                   tfp_fname : tfp_fname;{----Name of function or var       }
  126.                   tfp_faddr : POINTER;  {----FAR POINTER to function or var}
  127.                   tfp_ftype : tfp_ftype;{----Type of entry                 }
  128.                 END;
  129.  
  130.   tfp_fieptr  = ARRAY[1..1] OF tfp_fie_typ; {----Open Array Construction   }
  131.  
  132. VAR
  133.   fiearr      : ^tfp_fieptr;                  {----Array of functions & vars     }
  134.  
  135. {---------------------------------------------------------}
  136. {----Tricky stuff to call FUNCTIONS                       }
  137. {    Idea from Borland's DataBase ToolKit                 }
  138. {---------------------------------------------------------}
  139.  
  140. {$F+}
  141.  
  142. VAR
  143.   glueptr : POINTER;
  144.  
  145. FUNCTION Tfp_call_noparm : REAL;
  146.  
  147.  INLINE($ff/$1e/glueptr);  {CALL DWORD PTR GluePtr}
  148.  
  149. FUNCTION Tfp_call_1real(VAR lu_r) : REAL;
  150.  
  151.  INLINE($ff/$1e/glueptr);  {CALL DWORD PTR GluePtr}
  152.  
  153. FUNCTION Tfp_call_2real(VAR lu_r1,lu_r2) : REAL;
  154.  
  155.  INLINE($ff/$1e/glueptr);  {CALL DWORD PTR GluePtr}
  156.  
  157. FUNCTION Tfp_call_nreal(VAR lu_r,lu_n) : REAL;
  158.  
  159.  INLINE($ff/$1e/glueptr);  {CALL DWORD PTR GluePtr}
  160.  
  161. {$F-}
  162.  
  163. {---------------------------------------------------------}
  164. {----TP round function not useable                        }
  165. {---------------------------------------------------------}
  166.  
  167. FUNCTION Tfp_round(VAR r : REAL) : LONGINT;
  168.  
  169. BEGIN
  170.   IF (r<0)
  171.     THEN Tfp_round:= Trunc(r - 0.5)
  172.     ELSE Tfp_round:= Trunc(r + 0.5);
  173. END; {of Tfp_round}
  174.  
  175. {---------------------------------------------------------}
  176. {----This routine set the tfp_ernr if not set already     }
  177. {---------------------------------------------------------}
  178.  
  179. PROCEDURE Tfp_seternr(ernr : INTEGER);
  180.  
  181. BEGIN
  182.   IF (tfp_ernr=0)
  183.     THEN
  184.       BEGIN
  185.         tfp_erpos:=p^.tfp_lp;
  186.         tfp_ernr :=ernr;
  187.       END;
  188. END; {of Tfp_Seternr}
  189.  
  190. {---------------------------------------------------------}
  191. {----This routine skips one character                     }
  192. {---------------------------------------------------------}
  193.  
  194. PROCEDURE Tfp_newchar(p : tfp_state_ptr);
  195.  
  196. BEGIN
  197.   WITH p^ DO
  198.     BEGIN
  199.       IF (tfp_lp<Length(tfp_line))
  200.         THEN Inc(tfp_lp);
  201.       tfp_nextchar:=Upcase(tfp_line[tfp_lp]);
  202.     END;
  203. END; {of Tfp_Newchar}
  204.  
  205. {---------------------------------------------------------}
  206. {----This routine skips one character and                 }
  207. {    all folowing spaces from an expression               }
  208. {---------------------------------------------------------}
  209.  
  210. PROCEDURE Tfp_skip(p : tfp_state_ptr);
  211.  
  212. BEGIN
  213.   WITH p^ DO
  214.     REPEAT
  215.       Tfp_newchar(p);
  216.     UNTIL (tfp_nextchar<>' ');
  217. END; {of Tfp_Skip}
  218.  
  219. {---------------------------------------------------------}
  220. {----This Routine does some trivial check &               }
  221. {    Inits Tfp_State_Ptr^                                   }
  222. {---------------------------------------------------------}
  223.  
  224. PROCEDURE Tfp_check(s : STRING;p : tfp_state_ptr);
  225.  
  226. VAR
  227.   i,j        : INTEGER;
  228.  
  229. BEGIN
  230.   WITH p^ DO
  231.     BEGIN
  232.        tfp_lp:=0;
  233.  
  234.     {----Test for match on numbers of ( and ) }
  235.       j:=0;
  236.       FOR i:=1 TO Length(s) DO
  237.         CASE s[i] OF
  238.           '(' : Inc(j);
  239.           ')' : Dec(j);
  240.         END;
  241.  
  242.       IF (j=0)
  243.         THEN
  244.         {----Continue init}
  245.           BEGIN
  246.           {----Add a CHR(0) as an EOLN marker}
  247.             tfp_line:=s+#00;
  248.             Tfp_skip(p);
  249.  
  250.           {----Try parsing if any characters left}
  251.             IF (tfp_line[tfp_lp]=#00) THEN Tfp_seternr(6);
  252.           END
  253.       ELSE Tfp_seternr(3);
  254.     END;
  255. END; {of Tfp_Check}
  256.  
  257. {---------------------------------------------------------}
  258. {  Number     = Real    (Bv 23.4E-5)                      }
  259. {               Integer (Bv -45)                          }
  260. {---------------------------------------------------------}
  261.  
  262. FUNCTION Tfp_eval_number(p : tfp_state_ptr) : REAL;
  263.  
  264. VAR
  265.   temp  : STRING;
  266.   err   : INTEGER;
  267.   value : REAL;
  268.  
  269. BEGIN
  270.   WITH p^ DO
  271.     BEGIN
  272.     {----Correct .xx to 0.xx}
  273.       IF (tfp_nextchar='.')
  274.         THEN temp:='0'+tfp_nextchar
  275.         ELSE temp:=tfp_nextchar;
  276.  
  277.       Tfp_newchar(p);
  278.  
  279.     {----Correct ±.xx to ±0.xx}
  280.       IF (Length(temp)=1) AND
  281.          (temp[1] IN ['+','-']) AND
  282.          (tfp_nextchar='.')
  283.         THEN temp:=temp+'0';
  284.  
  285.       WHILE tfp_nextchar IN ['0'..'9','.','E'] DO
  286.         BEGIN
  287.           temp:=temp+tfp_nextchar;
  288.           IF (tfp_nextchar='E')
  289.             THEN
  290.               BEGIN
  291.               {----Correct ±xxx.E to ±xxx.0E}
  292.                 IF (temp[Length(temp)-1]='.')
  293.                   THEN Insert('0',temp,Length(temp));
  294.                 Tfp_newchar(p);
  295.                 IF (tfp_nextchar IN ['+','-'])
  296.                   THEN
  297.                     BEGIN
  298.                       temp:=temp+tfp_nextchar;
  299.                       Tfp_newchar(p);
  300.                     END;
  301.               END
  302.             ELSE Tfp_newchar(p);
  303.         END;
  304.  
  305.     {----Skip trailing spaces}
  306.       IF (tfp_nextchar=' ')
  307.         THEN Tfp_skip(p);
  308.  
  309.     {----Correct ±xx. to ±xx.0 but NOT ±xxE±yy.}
  310.       IF (temp[Length(temp)]='.') AND
  311.          (Pos('E',temp)=0)
  312.         THEN temp:=temp+'0';
  313.  
  314.       Val(temp,value,err);
  315.  
  316.       IF (err<>0) THEN Tfp_seternr(1);
  317.     END;
  318.  
  319.   IF (tfp_ernr=0)
  320.     THEN Tfp_eval_number:=value
  321.     ELSE Tfp_eval_number:=0;
  322.  
  323. END; {of Tfp_Eval_Number}
  324.  
  325. {---------------------------------------------------------}
  326. {  Factor     = Number                                    }
  327. {    (External) Function()                                }
  328. {    (External) Function(Expr)                            }
  329. {    (External) Function(Expr,Expr)                       }
  330. {     External  Var Real                                  }
  331. {     External  Var Integer                               }
  332. {     External  Var Boolean                               }
  333. {     External  Var realstring                            }
  334. {               (R_Expr)                                  }
  335. {---------------------------------------------------------}
  336.  
  337. FUNCTION Tfp_eval_b_expr(p : tfp_state_ptr) : REAL; forward;
  338.  
  339. FUNCTION Tfp_eval_factor(p : tfp_state_ptr) : REAL;
  340.  
  341. VAR
  342.   ferr     : BOOLEAN;
  343.   param    : INTEGER;
  344.   dummy    : tfp_rarray;
  345.   value,
  346.   dummy1,
  347.   dummy2   : REAL;
  348.   temp     : tfp_fname;
  349.   e,
  350.   i,
  351.   index    : INTEGER;
  352.   temps    : STRING;
  353.   tmpstate : tfp_state_ptr;
  354.  
  355. BEGIN
  356.   WITH p^ DO
  357.     CASE tfp_nextchar OF
  358.       '+' : BEGIN
  359.               Tfp_newchar(p);
  360.               value:=+Tfp_eval_factor(p);
  361.             END;
  362.  
  363.       '-' : BEGIN
  364.               Tfp_newchar(p);
  365.               value:=-Tfp_eval_factor(p);
  366.             END;
  367.  
  368.       '0'..
  369.       '9',
  370.       '.' : value:=Tfp_eval_number(p);
  371.  
  372.       'A'..
  373.       'Z' : BEGIN
  374.               ferr:=true;
  375.               temp:=tfp_nextchar;
  376.               Tfp_skip(p);
  377.               WHILE tfp_nextchar IN ['0'..'9','_','A'..'Z'] DO
  378.                 BEGIN
  379.                   temp:=temp+tfp_nextchar;
  380.                   Tfp_skip(p);
  381.                 END;
  382.  
  383.             {----Seek function and CALL it}
  384.               {$R-}
  385.               FOR index:=1 TO fiesiz DO
  386.                 WITH fiearr^[index] DO
  387.                   IF (tfp_fname=temp) THEN
  388.                     BEGIN
  389.                       ferr:=false;
  390.  
  391.                       CASE tfp_ftype OF
  392.  
  393.                       {----Function or Function()}
  394.                         tfp_noparm : IF (tfp_nextchar='(')
  395.                                        THEN
  396.                                          BEGIN
  397.                                            Tfp_skip(p);
  398.  
  399.                                            IF (tfp_nextchar<>')')
  400.                                              THEN Tfp_seternr(14);
  401.  
  402.                                            Tfp_skip(p);
  403.                                          END;
  404.  
  405.                       {----Function(r)}
  406.                         tfp_1real  : IF (tfp_nextchar='(')
  407.                                        THEN
  408.                                          BEGIN
  409.                                            Tfp_skip(p);
  410.  
  411.                                            dummy1:=Tfp_eval_b_expr(p);
  412.  
  413.                                            IF (tfp_ernr=0) AND
  414.                                               (tfp_nextchar<>')')
  415.                                              THEN Tfp_seternr(14);
  416.  
  417.                                            Tfp_skip(p); {----Dump the ')'}
  418.                                          END
  419.                                        ELSE Tfp_seternr(14);
  420.  
  421.                       {----Function(r1,r2)}
  422.                         tfp_2real  : IF (tfp_nextchar='(')
  423.                                        THEN
  424.                                          BEGIN
  425.                                            Tfp_skip(p);
  426.  
  427.                                            dummy1:=Tfp_eval_b_expr(p);
  428.  
  429.                                            IF (tfp_ernr=0) AND
  430.                                               (tfp_nextchar<>',')
  431.                                              THEN Tfp_seternr(14);
  432.  
  433.                                            Tfp_skip(p); {----Dump the ','}
  434.                                            dummy2:=Tfp_eval_b_expr(p);
  435.  
  436.                                             IF (tfp_ernr=0) AND
  437.                                                (tfp_nextchar<>')')
  438.                                               THEN Tfp_seternr(14);
  439.  
  440.                                             Tfp_skip(p); {----Dump the ')'}
  441.                                           END
  442.                                         ELSE Tfp_seternr(14);
  443.  
  444.                       {----Function(r,n)}
  445.                         tfp_nreal : IF (tfp_nextchar='(')
  446.                                       THEN
  447.                                         BEGIN
  448.                                           param:=0;
  449.  
  450.                                           Tfp_skip(p);
  451.                                           dummy[param]:=Tfp_eval_b_expr(p);
  452.  
  453.                                           IF (tfp_ernr=0) AND
  454.                                              (tfp_nextchar<>',')
  455.                                             THEN Tfp_seternr(14)
  456.                                             ELSE
  457.                                               WHILE (tfp_ernr=0) AND
  458.                                                     (tfp_nextchar=',') AND
  459.                                                     (param<tfp_maxparm-1) DO
  460.                                                 BEGIN
  461.                                                   Tfp_skip(p); {----Dump the ','}
  462.                                                   Inc(param);
  463.                                                   dummy[param]:=Tfp_eval_b_expr(p);
  464.                                                 END;
  465.  
  466.                                           IF (tfp_ernr=0) AND
  467.                                              (tfp_nextchar<>')')
  468.                                             THEN Tfp_seternr(14);
  469.  
  470.                                           Tfp_skip(p); {----Dump the ')'}
  471.                                         END
  472.                                       ELSE Tfp_seternr(14);
  473.  
  474.                       {----Real Var}
  475.                         tfp_realvar : dummy1:=REAL(tfp_faddr^);
  476.  
  477.                       {----Integer Var}
  478.                         tfp_intvar  : dummy1:=1.0*INTEGER(tfp_faddr^);
  479.  
  480.                       {----Boolean Var}
  481.                         tfp_boolvar : dummy1:=1.0*Ord(BOOLEAN(tfp_faddr^));
  482.  
  483.                       {----Real string Var}
  484.                         tfp_strvar  : BEGIN
  485.                                         temps:=STRING(tfp_faddr^);
  486.                                         IF (Maxavail>=Sizeof(tfp_parse_state))
  487.                                           THEN
  488.                                             BEGIN
  489.                                               New(tmpstate);
  490.                                               Tfp_check(temps,tmpstate);
  491.                                               dummy1:=Tfp_eval_b_expr(tmpstate);
  492.                                               Dispose(tmpstate);
  493.                                             END
  494.                                           ELSE Tfp_seternr(15);
  495.                                       END;
  496.                       END;
  497.  
  498.                       IF (tfp_ernr=0)
  499.                         THEN
  500.                           BEGIN
  501.                             glueptr:=tfp_faddr;
  502.  
  503.                             CASE tfp_ftype OF
  504.                               tfp_noparm  : value:=Tfp_call_noparm;
  505.                               tfp_1real   : value:=Tfp_call_1real(dummy1);
  506.                               tfp_2real   : value:=Tfp_call_2real(dummy1,dummy2);
  507.                               tfp_nreal   : value:=Tfp_call_nreal(dummy,param);
  508.                               tfp_realvar,
  509.                               tfp_intvar,
  510.                               tfp_boolvar,
  511.                               tfp_strvar  : value:=dummy1;
  512.                             END;
  513.                           END;
  514.                     END;
  515.               {$R+}
  516.  
  517.               IF (ferr=true)
  518.                 THEN Tfp_seternr(2);
  519.             END;
  520.  
  521.       '(' : BEGIN
  522.               Tfp_skip(p);
  523.  
  524.               value:=Tfp_eval_b_expr(p);
  525.  
  526.               IF (tfp_ernr=0) AND
  527.                  (tfp_nextchar<>')')
  528.                 THEN Tfp_seternr(3);
  529.  
  530.               Tfp_skip(p); {----Dump the ')'}
  531.             END;
  532.  
  533.     ELSE Tfp_seternr(2);
  534.     END;
  535.  
  536.   IF (tfp_ernr=0)
  537.     THEN Tfp_eval_factor:=value
  538.     ELSE Tfp_eval_factor:=0;
  539.  
  540. END; {of Tfp_Eval_factor}
  541.  
  542. {---------------------------------------------------------}
  543. {  Term       = Factor ^ Factor                           }
  544. {---------------------------------------------------------}
  545.  
  546. FUNCTION Tfp_eval_term(p : tfp_state_ptr) : REAL;
  547.  
  548. VAR
  549.   value,
  550.   exponent,
  551.   dummy,
  552.   base      : REAL;
  553.  
  554. BEGIN
  555.   WITH p^ DO
  556.     BEGIN
  557.       value:=Tfp_eval_factor(p);
  558.  
  559.       WHILE (tfp_ernr=0) AND (tfp_nextchar='^') DO
  560.         BEGIN
  561.           Tfp_skip(p);
  562.  
  563.           exponent:=Tfp_eval_factor(p);
  564.  
  565.           base:=value;
  566.           IF (tfp_ernr=0) AND (base=0)
  567.             THEN value:=0
  568.             ELSE
  569.               BEGIN
  570.  
  571.               {----Over/Underflow Protected}
  572.                 dummy:=exponent*Ln(Abs(base));
  573.                 IF (dummy<=Ln(tfp_maxreal))
  574.                    THEN value:=Exp(dummy)
  575.                    ELSE Tfp_seternr(11);
  576.               END;
  577.  
  578.           IF (tfp_ernr=0) AND (base<0)
  579.             THEN
  580.               BEGIN
  581.               {----Allow only whole number exponents,
  582.                    others will result in complex numbers}
  583.                 IF (Int(exponent)<>exponent)
  584.                   THEN Tfp_seternr(4);
  585.  
  586.                 IF (tfp_ernr=0) AND Odd(Tfp_round(exponent))
  587.                   THEN value:=-value;
  588.               END;
  589.         END;
  590.     END;
  591.  
  592.   IF (tfp_ernr=0)
  593.     THEN Tfp_eval_term:=value
  594.     ELSE Tfp_eval_term:=0;
  595.  
  596. END; {of Tfp_Eval_term}
  597.  
  598. {---------------------------------------------------------}
  599. {----Subterm  = Term * Term                               }
  600. {               Term / Term                               }
  601. {---------------------------------------------------------}
  602.  
  603. FUNCTION Tfp_eval_subterm(p : tfp_state_ptr) : REAL;
  604.  
  605. VAR
  606.   value,
  607.   dummy  : REAL;
  608.  
  609. BEGIN
  610.   WITH p^ DO
  611.     BEGIN
  612.       value:=Tfp_eval_term(p);
  613.  
  614.       WHILE (tfp_ernr=0) AND (tfp_nextchar IN ['*','/']) DO
  615.         CASE tfp_nextchar OF
  616.  
  617.         {----Over/Underflow Protected}
  618.           '*' : BEGIN
  619.                   Tfp_skip(p);
  620.  
  621.                   dummy:=Tfp_eval_term(p);
  622.  
  623.                   IF (tfp_ernr<>0) OR
  624.                      (value=0)     OR
  625.                      (dummy=0)
  626.                     THEN value:=0
  627.                     ELSE
  628.                       IF (Abs( Ln(Abs(value)) +
  629.                           Ln(Abs(dummy)) ) < Ln(tfp_maxreal))
  630.                         THEN value:= value * dummy
  631.                         ELSE Tfp_seternr(11);
  632.                 END;
  633.  
  634.         {----Over/Underflow Protected}
  635.           '/' : BEGIN
  636.                   Tfp_skip(p);
  637.  
  638.                   dummy:=Tfp_eval_term(p);
  639.  
  640.                   IF (tfp_ernr=0)
  641.                     THEN
  642.                       BEGIN
  643.  
  644.                       {----Division by ZERO Protected}
  645.                         IF (dummy<>0)
  646.                           THEN
  647.                             BEGIN
  648.  
  649.                             {----Underflow Protected}
  650.                               IF (value<>0)
  651.                                 THEN
  652.                                   BEGIN
  653.                                     IF (Abs( Ln(Abs(value)) -
  654.                                         Ln(Abs(dummy)) ) < Ln(tfp_maxreal))
  655.                                       THEN value:=value/dummy
  656.                                       ELSE Tfp_seternr(11)
  657.                                   END
  658.                                 ELSE value:=0;
  659.                             END
  660.                           ELSE Tfp_seternr(9);
  661.                       END;
  662.                 END;
  663.         END;
  664.     END;
  665.  
  666.   IF (tfp_ernr=0)
  667.     THEN Tfp_eval_subterm:=value
  668.     ELSE Tfp_eval_subterm:=0;
  669. END;{of Tfp_Eval_subterm}
  670.  
  671. {---------------------------------------------------------}
  672. {  Real Expr  = Subterm + Subterm                         }
  673. {               Subterm - Subterm                         }
  674. {---------------------------------------------------------}
  675.  
  676. FUNCTION Tfp_eval_r_expr(p : tfp_state_ptr) : REAL;
  677.  
  678. VAR
  679.   dummy,
  680.   dummy2,
  681.   value : REAL;
  682.  
  683. BEGIN
  684.   WITH p^ DO
  685.     BEGIN
  686.       value:=Tfp_eval_subterm(p);
  687.  
  688.       WHILE (tfp_ernr=0) AND (tfp_nextchar IN ['+','-']) DO
  689.         CASE tfp_nextchar OF
  690.  
  691.           '+' : BEGIN
  692.                   Tfp_skip(p);
  693.  
  694.                   dummy:=Tfp_eval_subterm(p);
  695.  
  696.                   IF (tfp_ernr=0)
  697.                     THEN
  698.                       BEGIN
  699.  
  700.                       {----Overflow Protected}
  701.                         IF (Abs( (value/10) + (dummy/10) ) < (tfp_maxreal/10))
  702.                           THEN value:=value+dummy
  703.                           ELSE Tfp_seternr(11);
  704.                       END;
  705.                 END;
  706.  
  707.           '-' : BEGIN
  708.                   Tfp_skip(p);
  709.                   dummy2:=value;
  710.  
  711.                   dummy:=Tfp_eval_subterm(p);
  712.  
  713.                   IF (tfp_ernr=0)
  714.                     THEN
  715.                       BEGIN
  716.  
  717.                       {----Overflow Protected}
  718.                         IF (Abs( (value/10) - (dummy/10) )<(tfp_maxreal/10))
  719.                           THEN value:=value-dummy
  720.                           ELSE Tfp_seternr(11);
  721.  
  722.                       {----Underflow Protected}
  723.                         IF (value=0) AND (dummy<>dummy2)
  724.                           THEN Tfp_seternr(11);
  725.                       END;
  726.                 END;
  727.         END;
  728.  
  729.     {----at this point the current char must be }
  730.     {       1. the eoln marker or               }
  731.     {       2. a right bracket                  }
  732.     {       3. start of a boolean operator      }
  733.  
  734.       IF NOT (tfp_nextchar IN [#00,')','>','<','=',','])
  735.         THEN Tfp_seternr(2);
  736.     END;
  737.  
  738.   IF (tfp_ernr=0)
  739.     THEN Tfp_eval_r_expr:=value
  740.     ELSE Tfp_eval_r_expr:=0;
  741. END; {of Tfp_Eval_R_Expr}
  742.  
  743. {---------------------------------------------------------}
  744. {  Boolean Expr  = R_Expr <  R_Expr                       }
  745. {                  R_Expr <= R_Expr                       }
  746. {                  R_Expr <> R_Expr                       }
  747. {                  R_Expr =  R_Expr                       }
  748. {                  R_Expr >= R_Expr                       }
  749. {                  R_Expr >  R_Expr                       }
  750. {---------------------------------------------------------}
  751.  
  752. FUNCTION Tfp_eval_b_expr(p : tfp_state_ptr) : REAL;
  753.  
  754. VAR
  755.   value : REAL;
  756.  
  757. BEGIN
  758.   WITH p^ DO
  759.     BEGIN
  760.       value:=Tfp_eval_r_expr(p);
  761.  
  762.       IF (tfp_ernr=0) AND (tfp_nextchar IN ['<','>','=']) THEN
  763.         CASE tfp_nextchar OF
  764.  
  765.           '<' : BEGIN
  766.                   Tfp_skip(p);
  767.                   IF (tfp_nextchar IN ['>','='])
  768.                     THEN
  769.                       CASE tfp_nextchar OF
  770.                         '>' : BEGIN
  771.                                 Tfp_skip(p);
  772.                                 IF (value<>Tfp_eval_r_expr(p))
  773.                                   THEN value:=tfp_true
  774.                                   ELSE value:=tfp_false;
  775.                               END;
  776.  
  777.                         '=' : BEGIN
  778.                                 Tfp_skip(p);
  779.                                 IF (value<=Tfp_eval_r_expr(p))
  780.                                   THEN value:=tfp_true
  781.                                   ELSE value:=tfp_false;
  782.                               END;
  783.                       END
  784.                       ELSE
  785.                         BEGIN
  786.                           IF (value<Tfp_eval_r_expr(p))
  787.                             THEN value:=tfp_true
  788.                             ELSE value:=tfp_false;
  789.                         END;
  790.                 END;
  791.  
  792.           '>' : BEGIN
  793.                   Tfp_skip(p);
  794.                   IF (tfp_nextchar='=')
  795.                     THEN
  796.                       BEGIN
  797.                         Tfp_skip(p);
  798.                         IF (value>=Tfp_eval_r_expr(p))
  799.                           THEN value:=tfp_true
  800.                           ELSE value:=tfp_false;
  801.                       END
  802.                     ELSE
  803.                       BEGIN
  804.                         IF (value>Tfp_eval_r_expr(p))
  805.                           THEN value:=tfp_true
  806.                           ELSE value:=tfp_false;
  807.                       END;
  808.                 END;
  809.  
  810.           '=' : BEGIN
  811.                   Tfp_skip(p);
  812.                   IF (value=Tfp_eval_r_expr(p))
  813.                     THEN value:=tfp_true
  814.                     ELSE value:=tfp_false;
  815.                 END;
  816.         END;
  817.     END;
  818.  
  819.   IF (tfp_ernr=0)
  820.     THEN Tfp_eval_b_expr:=value
  821.     ELSE Tfp_eval_b_expr:=0.0;
  822. END; {of Tfp_Eval_B_Expr}
  823.  
  824. {---------------------------------------------------------}
  825.  
  826. FUNCTION Tfp_parse2real(s : STRING): REAL;
  827.  
  828. VAR
  829.   value   : REAL;
  830.  
  831. BEGIN
  832.   tfp_erpos:=0;
  833.   tfp_ernr :=0;
  834.  
  835.   IF Maxavail>=Sizeof(tfp_parse_state)
  836.     THEN
  837.       BEGIN
  838.         New(p);
  839.         Tfp_check(s,p);
  840.  
  841.         IF (tfp_ernr=0)
  842.           THEN value:=Tfp_eval_b_expr(p);
  843.  
  844.         Dispose(p);
  845.       END
  846.     ELSE Tfp_seternr(15);
  847.  
  848.   IF (tfp_ernr<>0)
  849.     THEN Tfp_parse2real:=0.0
  850.     ELSE Tfp_parse2real:=value;
  851.  
  852. END; {of Tfp_Parse2Real}
  853.  
  854. {---------------------------------------------------------}
  855.  
  856. FUNCTION Tfp_parse2str(s : STRING;m,n : INTEGER) : STRING;
  857.  
  858. VAR
  859.   r   : REAL;
  860.   tmp : STRING;
  861.  
  862. BEGIN
  863.   r:=Tfp_parse2real(s);
  864.   IF (tfp_ernr=0)
  865.     THEN Str(r:m:n,tmp)
  866.     ELSE tmp:='';
  867.   Tfp_parse2str:=tmp;
  868. END; {of Tfp_Parse2str}
  869.  
  870. {---------------------------------------------------------}
  871.  
  872. FUNCTION Tfp_errormsg(nr : INTEGER) : STRING;
  873.  
  874. BEGIN
  875.   CASE nr OF
  876.     0 : Tfp_errormsg:='Result ok';                                  {Error 0 }
  877.     1 : Tfp_errormsg:='Invalid format of a number';                 {Error 1 }
  878.     2 : Tfp_errormsg:='Unkown function';                            {Error 2 }
  879.     3 : Tfp_errormsg:='( ) mismatch';                               {Error 3 }
  880.     4 : Tfp_errormsg:='Real exponent -> complex number';            {Error 4 }
  881.     5 : Tfp_errormsg:='TAN( (2n+1)*PI/2 ) not defined';             {Error 5 }
  882.     6 : Tfp_errormsg:='Empty string';                               {Error 6 }
  883.     7 : Tfp_errormsg:='LN(x) or LOG(x) for x<=0 -> complex number'; {Error 7 }
  884.     8 : Tfp_errormsg:='SQRT(x) for x<0 -> complex number';          {Error 8 }
  885.     9 : Tfp_errormsg:='Divide by zero';                             {Error 9 }
  886.    10 : Tfp_errormsg:='To many function or constants';              {Error 10}
  887.    11 : Tfp_errormsg:='Intermediate result out of range';           {Error 11}
  888.    12 : Tfp_errormsg:='Illegal characters in functionname';         {Error 12}
  889.    13 : Tfp_errormsg:='Not a boolean expression';                   {Error 13}
  890.    14 : Tfp_errormsg:='Wrong number of parameters';                 {Error 14}
  891.    15 : Tfp_errormsg:='Memory problems';                            {Error 15}
  892.    16 : Tfp_errormsg:='Not enough functions or constants';          {Error 16}
  893.    17 : Tfp_errormsg:='Csc( n*PI ) not defined';                    {Error 17}
  894.    18 : Tfp_errormsg:='Sec( (2n+1)*PI/2 ) not defined';             {Error 18}
  895.    19 : Tfp_errormsg:='Cot( n*PI ) not defined';                    {Error 19}
  896.    20 : Tfp_errormsg:='Parameter to large';                         {Error 20}
  897.    21 : Tfp_errormsg:='Csch(0) not defined';                        {Error 21}
  898.    22 : Tfp_errormsg:='Coth(0) not defined';                        {Error 22}
  899.    23 : Tfp_errormsg:='ArcCosh(x) not defined for x<1';             {Error 23}
  900.    24 : Tfp_errormsg:='ArcTanh(x) not defined for Abs(x)=>1';       {Error 24}
  901.    25 : Tfp_errormsg:='Arccsch(0) not defined';                     {Error 25}
  902.    26 : Tfp_errormsg:='Arcsech(x) not defined for x<=0 or x>1';     {Error 26}
  903.    27 : Tfp_errormsg:='Arccoth(x) not defined for Abs(x)<=1';       {Error 27}
  904.   ELSE  Tfp_errormsg:='Unkown error';                               {Error xx}
  905.   END;
  906. END; {of Tfp_ermsg}
  907.  
  908. {---------------------------------------------------------}
  909.  
  910. PROCEDURE Tfp_init(no : WORD);
  911.  
  912. BEGIN
  913.   IF (maxfie>0)
  914.     THEN Freemem(fiearr,maxfie*Sizeof(tfp_fie_typ));
  915.  
  916.   maxfie:=0;
  917.   fiesiz:=0;
  918.  
  919.   IF (Maxavail>=(no*Sizeof(tfp_fie_typ))) AND (no>0)
  920.     THEN
  921.       BEGIN
  922.         getmem(fiearr,no*Sizeof(tfp_fie_typ));
  923.         maxfie:=no;
  924.       END
  925.     ELSE Tfp_seternr(15);
  926. END; {of Tfp_Init}
  927.  
  928. {---------------------------------------------------------}
  929.  
  930. PROCEDURE Tfp_expand(no : WORD);
  931.  
  932. VAR
  933.   temp : ^tfp_fieptr;
  934.  
  935. BEGIN
  936.   IF (maxfie>0) AND (no>0)
  937.     THEN
  938.       BEGIN
  939.         IF (Maxavail>=(maxfie+no)*Sizeof(tfp_fie_typ))
  940.           THEN
  941.             BEGIN
  942.               getmem(temp,(maxfie+no)*Sizeof(tfp_fie_typ));
  943.               Move(fiearr^,temp^,maxfie*Sizeof(tfp_fie_typ));
  944.               Freemem(fiearr,maxfie*Sizeof(tfp_fie_typ));
  945.               fiearr:=POINTER(temp);
  946.               maxfie:=maxfie+no;
  947.               fiesiz:=fiesiz;
  948.             END
  949.           ELSE Tfp_seternr(15)
  950.       END
  951.     ELSE Tfp_init(no);
  952. END; {of Tfp_Expand}
  953.  
  954. {---------------------------------------------------------}
  955.  
  956. PROCEDURE Tfp_keep(no : WORD);
  957.  
  958. BEGIN
  959.   IF (maxfie<no)
  960.     THEN Tfp_seternr(16)
  961.     ELSE maxfie:=no;
  962. END; {of Tfp_Keep}
  963.  
  964. {---------------------------------------------------------}
  965.  
  966. FUNCTION Tfp_noobj : WORD;
  967.  
  968. BEGIN
  969.   Tfp_noobj:=maxfie;
  970. END; {of Tfp_Noobj}
  971.  
  972. {---------------------------------------------------------}
  973.  
  974. PROCEDURE Tfp_addobj(adres : POINTER;name : tfp_fname;ftype : tfp_ftype);
  975.  
  976. VAR
  977.   i : INTEGER;
  978.  
  979. BEGIN
  980. {$R-}
  981.   IF (fiesiz<maxfie)
  982.     THEN
  983.       BEGIN
  984.         Inc(fiesiz);
  985.         WITH fiearr^[fiesiz] DO
  986.           BEGIN
  987.             tfp_faddr:=adres;
  988.             tfp_fname:=name;
  989.             FOR i:=1 TO Length(tfp_fname) DO
  990.               IF (Upcase(tfp_fname[i]) IN ['0'..'9','_','A'..'Z'])
  991.                 THEN tfp_fname[i]:=Upcase(tfp_fname[i])
  992.                 ELSE Tfp_seternr(12);
  993.  
  994.             IF (Length(tfp_fname)>0) AND
  995.                NOT (tfp_fname[1] IN ['A'..'Z'])
  996.               THEN Tfp_seternr(12);
  997.  
  998.             tfp_ftype:=ftype;
  999.           END
  1000.       END
  1001.     ELSE Tfp_seternr(10);
  1002. {$R+}
  1003. END; {of Tfp_Addobject}
  1004.  
  1005. {---------------------------------------------------------}
  1006. {----Internal Functions                                   }
  1007. {---------------------------------------------------------}
  1008.  
  1009. {$F+}
  1010.  
  1011. FUNCTION Xabs(VAR r : REAL) : REAL;
  1012.  
  1013. BEGIN
  1014.   Xabs:=Abs(r);
  1015. END; {of xABS}
  1016.  
  1017. {---------------------------------------------------------}
  1018.  
  1019. FUNCTION Xand(VAR lu_r;VAR n : INTEGER) : REAL;
  1020.  
  1021. VAR
  1022.   r  : REAL;
  1023.   i  : INTEGER;
  1024.  
  1025. BEGIN
  1026.   FOR i:=0 TO n DO
  1027.     IF (tfp_rarray(lu_r)[i]<>tfp_false) AND
  1028.        (tfp_rarray(lu_r)[i]<>tfp_true)
  1029.       THEN
  1030.         BEGIN
  1031.           IF (tfp_ernr=0)
  1032.             THEN Tfp_seternr(13);
  1033.         END;
  1034.  
  1035.   IF (tfp_ernr=0) AND (n>0)
  1036.     THEN
  1037.       BEGIN
  1038.         r:=tfp_true*Ord(tfp_rarray(lu_r)[0]=tfp_true);
  1039.         FOR i:=1 TO n DO
  1040.           r:=tfp_true*Ord( (r=tfp_true) AND (tfp_rarray(lu_r)[i]=tfp_true))
  1041.       END
  1042.     ELSE Tfp_seternr(14);
  1043.  
  1044.   IF tfp_ernr=0
  1045.     THEN Xand:=r
  1046.     ELSE Xand:=0.0;
  1047. END; {of xAND}
  1048.  
  1049. {---------------------------------------------------------}
  1050.  
  1051. FUNCTION Xarctan(VAR r : REAL) : REAL;
  1052.  
  1053. BEGIN
  1054.   Xarctan:=Arctan(r);
  1055. END; {of xArctan}
  1056.  
  1057. {---------------------------------------------------------}
  1058.  
  1059. FUNCTION Xcos(VAR r : REAL) : REAL;
  1060.  
  1061. BEGIN
  1062.   Xcos:=Cos(r);
  1063. END; {of xCos}
  1064.  
  1065. {---------------------------------------------------------}
  1066.  
  1067. FUNCTION Xdeg(VAR r : REAL) : REAL;
  1068.  
  1069. BEGIN
  1070.   Xdeg:=(r/pi)*180;
  1071. END; {of xDEG}
  1072.  
  1073. {---------------------------------------------------------}
  1074.  
  1075. FUNCTION Xe : REAL;
  1076.  
  1077. BEGIN
  1078.   Xe:=Exp(1);
  1079. END; {of xE}
  1080.  
  1081. {---------------------------------------------------------}
  1082.  
  1083. FUNCTION Xexp(VAR r : REAL) : REAL;
  1084.  
  1085. BEGIN
  1086.   Xexp:=0;
  1087.   IF (Abs(r)<Ln(tfp_maxreal))
  1088.     THEN Xexp:=Exp(r)
  1089.     ELSE Tfp_seternr(11);
  1090. END; {of xExp}
  1091.  
  1092. {---------------------------------------------------------}
  1093.  
  1094. FUNCTION Xfalse : REAL;
  1095.  
  1096. BEGIN
  1097.   Xfalse:=tfp_false;
  1098. END; {of xFalse}
  1099.  
  1100. {---------------------------------------------------------}
  1101.  
  1102. FUNCTION Xfrac(VAR r : REAL) : REAL;
  1103.  
  1104. BEGIN
  1105.   Xfrac:=Frac(r);
  1106. END; {of xFrac}
  1107.  
  1108. {---------------------------------------------------------}
  1109.  
  1110. FUNCTION Xint(VAR r : REAL) : REAL;
  1111.  
  1112. BEGIN
  1113.   Xint:=Int(r);
  1114. END; {of xInt}
  1115.  
  1116. {---------------------------------------------------------}
  1117.  
  1118. FUNCTION Xln(VAR r : REAL) : REAL;
  1119.  
  1120. BEGIN
  1121.   Xln:=0;
  1122.   IF (r>0)
  1123.     THEN Xln:=Ln(r)
  1124.     ELSE Tfp_seternr(7);
  1125. END; {of xLn}
  1126.  
  1127. {---------------------------------------------------------}
  1128.  
  1129. FUNCTION Xlog(VAR r : REAL) : REAL;
  1130.  
  1131. BEGIN
  1132.   Xlog:=0;
  1133.   IF (r>0)
  1134.     THEN Xlog:=Ln(r)/ln(10)
  1135.     ELSE Tfp_seternr(7);
  1136. END; {of xLog}
  1137.  
  1138. {---------------------------------------------------------}
  1139.  
  1140. FUNCTION Xmax(VAR lu_r;VAR n : INTEGER) : REAL;
  1141.  
  1142. VAR
  1143.   max   : REAL;
  1144.   i        : INTEGER;
  1145.  
  1146. BEGIN
  1147.   max:=tfp_rarray(lu_r)[0];
  1148.   FOR i:=1 TO n DO
  1149.     IF (tfp_rarray(lu_r)[i]>max)
  1150.       THEN max:=tfp_rarray(lu_r)[i];
  1151.   Xmax:=max;
  1152. END; {of xMax}
  1153.  
  1154. {---------------------------------------------------------}
  1155.  
  1156. FUNCTION Xmin(VAR lu_r;VAR n : INTEGER) : REAL;
  1157.  
  1158. VAR
  1159.   min   : REAL;
  1160.   i     : INTEGER;
  1161.  
  1162. BEGIN
  1163.   min:=tfp_rarray(lu_r)[0];
  1164.   FOR i:=1 TO n DO
  1165.     IF (tfp_rarray(lu_r)[i]<min)
  1166.       THEN min:=tfp_rarray(lu_r)[i];
  1167.   Xmin:=min;
  1168. END; {of xMin}
  1169.  
  1170. {---------------------------------------------------------}
  1171.  
  1172. FUNCTION Xior(VAR lu_r;VAR n : INTEGER) : REAL;
  1173.  
  1174. VAR
  1175.   r : REAL;
  1176.   i : INTEGER;
  1177.  
  1178. BEGIN
  1179.   FOR i:=0 TO n DO
  1180.     IF (tfp_rarray(lu_r)[i]<>tfp_false) AND
  1181.        (tfp_rarray(lu_r)[i]<>tfp_true)
  1182.       THEN
  1183.         BEGIN
  1184.           IF (tfp_ernr=0)
  1185.             THEN Tfp_seternr(13);
  1186.         END;
  1187.  
  1188.   IF (tfp_ernr=0) AND
  1189.      (n>0)
  1190.     THEN
  1191.       BEGIN
  1192.         r:=tfp_true*Ord(tfp_rarray(lu_r)[0]=tfp_true);
  1193.         FOR i:=1 TO n DO
  1194.           r:=tfp_true*Ord((r=tfp_true) OR (tfp_rarray(lu_r)[i]=tfp_true))
  1195.       END
  1196.     ELSE Tfp_seternr(14);
  1197.  
  1198.   IF tfp_ernr=0
  1199.     THEN Xior:=r
  1200.     ELSE Xior:=Tfp_false;
  1201. END; {of xIor}
  1202.  
  1203. {---------------------------------------------------------}
  1204.  
  1205. FUNCTION Xpi : REAL;
  1206.  
  1207. BEGIN
  1208.   Xpi:=Pi;
  1209. END; {of xPi}
  1210.  
  1211. {---------------------------------------------------------}
  1212.  
  1213. FUNCTION Xrad(VAR r : REAL) : REAL;
  1214.  
  1215. BEGIN
  1216.   Xrad:=(r/180)*Pi;
  1217. END; {of xRad}
  1218.  
  1219. {---------------------------------------------------------}
  1220.  
  1221. FUNCTION Xround(VAR r : REAL) : REAL;
  1222.  
  1223. BEGIN
  1224.   IF (Abs(r)<tfp_maxlongint)
  1225.     THEN Xround:=Tfp_round(r)
  1226.     ELSE Xround:=r;
  1227. END; {of xRound}
  1228.  
  1229. {---------------------------------------------------------}
  1230.  
  1231. FUNCTION Xsgn(VAR r : REAL) : REAL;
  1232.  
  1233. BEGIN
  1234.   IF (r>=0)
  1235.     THEN Xsgn:=+1
  1236.     ELSE Xsgn:=-1;
  1237. END; {of xSgn}
  1238.  
  1239. {---------------------------------------------------------}
  1240.  
  1241. FUNCTION Xsin(VAR r : REAL) : REAL;
  1242.  
  1243. BEGIN
  1244.   Xsin:=Sin(r);
  1245. END; {of xSin}
  1246.  
  1247. {---------------------------------------------------------}
  1248.  
  1249. FUNCTION Xsqr(VAR r : REAL) : REAL;
  1250.  
  1251. BEGIN
  1252.   Xsqr:=0;
  1253.   IF (Abs(r)>0)
  1254.     THEN
  1255.       BEGIN
  1256.         IF ( Abs(2*Ln(Abs(r))) )<Ln(tfp_maxreal)
  1257.           THEN Xsqr:=Exp( 2*Ln(Abs(r)) )
  1258.           ELSE Tfp_seternr(11);
  1259.       END;
  1260. END; {of xSqr}
  1261.  
  1262. {---------------------------------------------------------}
  1263.  
  1264. FUNCTION Xsqrt(VAR r : REAL) : REAL;
  1265.  
  1266. BEGIN
  1267.   Xsqrt:=0;
  1268.   IF (r>=0)
  1269.     THEN Xsqrt:=Sqrt(r)
  1270.     ELSE Tfp_seternr(8);
  1271. END; {of xSqrt}
  1272.  
  1273. {---------------------------------------------------------}
  1274.  
  1275. FUNCTION Xtan(VAR r : REAL) : REAL;
  1276.  
  1277. BEGIN
  1278.   Xtan:=0;
  1279.   IF (Cos(r)=0)
  1280.     THEN Tfp_seternr(5)
  1281.     ELSE Xtan:=Sin(r)/cos(r);
  1282. END; {of xTan}
  1283.  
  1284. {---------------------------------------------------------}
  1285.  
  1286. FUNCTION Xtrue : REAL;
  1287.  
  1288. BEGIN
  1289.   Xtrue:=tfp_true;
  1290. END; {of xTrue}
  1291.  
  1292. {---------------------------------------------------------}
  1293.  
  1294. FUNCTION Xxor(VAR r1,r2 : REAL) : REAL;
  1295.  
  1296. BEGIN
  1297.  Xxor:=tfp_false;
  1298.  IF ((r1<>tfp_false) AND (r1<>tfp_true)) OR
  1299.     ((r2<>tfp_false) AND (r2<>tfp_true))
  1300.    THEN
  1301.      BEGIN
  1302.        IF (tfp_ernr=0)
  1303.          THEN Tfp_seternr(13);
  1304.      END
  1305.    ELSE Xxor:=tfp_true*Ord((r1=tfp_true) XOR (r2=tfp_true));
  1306. END; {of xXOR}
  1307.  
  1308. {---------------------------------------------------------}
  1309. {----Hyperbolic, reciproce and inverse goniometric        }
  1310. {    functions                                            }
  1311. {---------------------------------------------------------}
  1312.  
  1313. Function xCsc(VAR r: Real): Real;
  1314.  
  1315. Begin;
  1316.   xCsc:=0;
  1317.   IF (Sin(r)=0)
  1318.     THEN Tfp_seternr(17)
  1319.     ELSE xCsc:=1/Sin(r);
  1320. End; {xCsc}
  1321.  
  1322. {---------------------------------------------------------}
  1323.  
  1324. Function xSec(VAR r: Real): Real;
  1325.  
  1326. Begin;
  1327.   xSec:=0;
  1328.   IF (Cos(r)=0)
  1329.     THEN Tfp_seternr(18)
  1330.     ELSE xSec:=1/Cos(r);
  1331. End; {xSec}
  1332.  
  1333. {---------------------------------------------------------}
  1334.  
  1335. Function xCot(VAR r : Real): Real;
  1336.  
  1337. Begin;
  1338.   xCot:=0;
  1339.   IF (Sin(r)=0)
  1340.     THEN Tfp_seternr(19)
  1341.     ELSE xCot:=Cos(r)/Sin(r);
  1342. End; {xCot}
  1343.  
  1344. {---------------------------------------------------------}
  1345.  
  1346. FUNCTION xCosh(VAR r : REAL) : REAL;
  1347.  
  1348. BEGIN
  1349.   xCosh:=0;
  1350.   IF (Abs(r)>Ln(tfp_maxreal))
  1351.     THEN Tfp_seternr(20)
  1352.     ELSE xCosh:=(Exp(r)+Exp(-r))/2;
  1353. END; {of xCosh}
  1354.  
  1355. {---------------------------------------------------------}
  1356.  
  1357. FUNCTION xSinh(VAR r : REAL) : REAL;
  1358.  
  1359. BEGIN
  1360.   xSinh:=0;
  1361.   IF (Abs(r)>Ln(tfp_maxreal))
  1362.     THEN Tfp_seternr(20)
  1363.     ELSE xSinh:=(Exp(r)-Exp(-r))/2;
  1364. END;  {of xSinh}
  1365.  
  1366. {---------------------------------------------------------}
  1367.  
  1368. FUNCTION xTanh(VAR r : REAL) : REAL;
  1369.  
  1370. BEGIN
  1371.   xTanh:=0;
  1372.   IF (Abs(r)>Ln(tfp_maxreal))
  1373.     THEN Tfp_seternr(20)
  1374.     ELSE xTanh:=(Exp(r)-Exp(-r))/(Exp(r)+Exp(-r));
  1375. END; {of xTanh}
  1376.  
  1377. {---------------------------------------------------------}
  1378.  
  1379. FUNCTION xCsch(VAR r : REAL) : REAL;
  1380.  
  1381. BEGIN
  1382.   xCsch:=0;
  1383.   IF (Abs(r)>Ln(tfp_maxreal))
  1384.     THEN Tfp_seternr(20)
  1385.     ELSE
  1386.       BEGIN
  1387.         IF (r=0)
  1388.           THEN Tfp_seternr(21)
  1389.           ELSE xCsch:=2/(Exp(r)-Exp(-r))
  1390.       END;
  1391. END; {of xCsch}
  1392.  
  1393. {---------------------------------------------------------}
  1394.  
  1395. FUNCTION xSech(VAR r : REAL) : REAL;
  1396.  
  1397. BEGIN
  1398.   xSech:=0;
  1399.   IF (Abs(r)>Ln(tfp_maxreal))
  1400.     THEN Tfp_seternr(20)
  1401.     ELSE xSech:=2/(Exp(r)+Exp(-r));
  1402. END; {of xSech}
  1403.  
  1404. {---------------------------------------------------------}
  1405.  
  1406. FUNCTION xCoth(VAR r : REAL) : REAL;
  1407.  
  1408. BEGIN
  1409.   xCoth:=0;
  1410.   IF (Abs(r)>Ln(tfp_maxreal))
  1411.     THEN Tfp_seternr(20)
  1412.     ELSE
  1413.       BEGIN
  1414.         IF (r=0)
  1415.           THEN Tfp_seternr(22)
  1416.           ELSE xCoth:=(Exp(r)+Exp(-r))/(Exp(r)-Exp(-r))
  1417.       END;
  1418. END; {of xCoth}
  1419.  
  1420. {---------------------------------------------------------}
  1421.  
  1422. FUNCTION xArcsinh(VAR r : REAL) : REAL;
  1423.  
  1424. BEGIN
  1425.   xArcsinh:=0;
  1426.   IF (Abs(r)<SQRT(tfp_maxreal))
  1427.     THEN xArcsinh:=Ln(r+Sqrt(Sqr(r)+1))
  1428.     ELSE Tfp_seternr(20)
  1429. END; {of xArcsinh}
  1430.  
  1431. {---------------------------------------------------------}
  1432.  
  1433. FUNCTION xArccosh(VAR r : REAL) : REAL;
  1434.  
  1435. BEGIN
  1436.   xArccosh:=0;
  1437.   IF (Abs(r)<SQRT(tfp_maxreal))
  1438.     THEN
  1439.       BEGIN
  1440.         IF (r>=1)
  1441.           THEN xArccosh:=ln(r+Sqrt(Sqr(r)-1))
  1442.           ELSE Tfp_seternr(23);
  1443.       END
  1444.     ELSE Tfp_seternr(20)
  1445. END; {of xArccosh}
  1446.  
  1447. {---------------------------------------------------------}
  1448.  
  1449. FUNCTION xArctanh(VAR r : REAL) : REAL;
  1450.  
  1451. BEGIN
  1452.   xArctanh:=0;
  1453.   IF (Abs(r)<1)
  1454.     THEN xArctanh:=ln( (1+r)/(1-r) )/2
  1455.     ELSE Tfp_seternr(24)
  1456. END; {of xArctanh}
  1457.  
  1458. {---------------------------------------------------------}
  1459.  
  1460. FUNCTION xArccsch(VAR r : REAL) : REAL;
  1461.  
  1462. BEGIN
  1463.   xArccsch:=0;
  1464.   IF (r<SQRT(Tfp_maxreal))
  1465.     THEN
  1466.       BEGIN
  1467.         IF (r<>0)
  1468.           THEN xArccsch:=Ln( (1/r) + SQRT( (1/SQR(r))+1))
  1469.           ELSE Tfp_seternr(25)
  1470.       END
  1471.     ELSE Tfp_seternr(20);
  1472. END; {of xArccsch}
  1473.  
  1474. {---------------------------------------------------------}
  1475.  
  1476. FUNCTION xArcsech(VAR r : REAL) : REAL;
  1477.  
  1478. BEGIN
  1479.   xArcsech:=0;
  1480.   IF (r<SQRT(Tfp_maxreal))
  1481.     THEN
  1482.       BEGIN
  1483.         IF (r>0) AND (r<=1)
  1484.           THEN xArcsech:=Ln( (1/r) + SQRT( (1/SQR(r))-1))
  1485.           ELSE Tfp_seternr(26)
  1486.       END
  1487.     ELSE Tfp_seternr(20)
  1488. END; {of xArcsech}
  1489.  
  1490. {---------------------------------------------------------}
  1491.  
  1492. FUNCTION xArccoth(VAR r : REAL) : REAL;
  1493.  
  1494. BEGIN
  1495.   xArccoth:=0;
  1496.   IF (Abs(r)>1)
  1497.     THEN xArccoth:=Ln( (r+1)/(r-1) )/2
  1498.     ELSE Tfp_seternr(27)
  1499. END; {of xArccoth}
  1500.  
  1501. {$F-}
  1502.  
  1503. {---------------------------------------------------------}
  1504.  
  1505. PROCEDURE Tfp_addgonio;
  1506.  
  1507. BEGIN
  1508.   Tfp_expand(7);
  1509.   Tfp_addobj(@xarctan,'ARCTAN',tfp_1real);
  1510.   Tfp_addobj(@xcos   ,'COS'   ,tfp_1real);
  1511.   Tfp_addobj(@xdeg   ,'DEG'   ,tfp_1real);
  1512.   Tfp_addobj(@xpi    ,'PI'    ,tfp_noparm);
  1513.   Tfp_addobj(@xrad   ,'RAD'   ,tfp_1real);
  1514.   Tfp_addobj(@xsin   ,'SIN'   ,tfp_1real);
  1515.   Tfp_addobj(@xtan   ,'TAN'   ,tfp_1real);
  1516. END; {of Tfp_Addgonio}
  1517.  
  1518. {---------------------------------------------------------}
  1519.  
  1520. PROCEDURE Tfp_addlogic;
  1521.  
  1522. BEGIN
  1523.   Tfp_expand(5);
  1524.   Tfp_addobj(@xand      ,'AND'   ,tfp_nreal);
  1525.   Tfp_addobj(@xfalse    ,'FALSE' ,tfp_noparm);
  1526.   Tfp_addobj(@xior      ,'OR'    ,tfp_nreal);
  1527.   Tfp_addobj(@xtrue     ,'TRUE'  ,tfp_noparm);
  1528.   Tfp_addobj(@xxor      ,'XOR'   ,tfp_2real);
  1529. END; {of Tfp_Addlogic}
  1530.  
  1531. {---------------------------------------------------------}
  1532.  
  1533. PROCEDURE Tfp_addmath;
  1534.  
  1535. BEGIN
  1536.   Tfp_expand(7);
  1537.   Tfp_addobj(@xabs   ,'ABS'   ,tfp_1real);
  1538.   Tfp_addobj(@xexp   ,'EXP'   ,tfp_1real);
  1539.   Tfp_addobj(@xe     ,'E'     ,tfp_noparm);
  1540.   Tfp_addobj(@xln    ,'LN'    ,tfp_1real);
  1541.   Tfp_addobj(@xlog   ,'LOG'   ,tfp_1real);
  1542.   Tfp_addobj(@xsqr   ,'SQR'   ,tfp_1real);
  1543.   Tfp_addobj(@xsqrt  ,'SQRT'  ,tfp_1real);
  1544. END; {of Tfp_Addmath}
  1545.  
  1546. {---------------------------------------------------------}
  1547.  
  1548. PROCEDURE Tfp_addmisc;
  1549.  
  1550. BEGIN
  1551.   Tfp_expand(6);
  1552.   Tfp_addobj(@xfrac  ,'FRAC'  ,tfp_1real);
  1553.   Tfp_addobj(@xint   ,'INT'   ,tfp_1real);
  1554.   Tfp_addobj(@xmax   ,'MAX'   ,tfp_nreal);
  1555.   Tfp_addobj(@xmin   ,'MIN'   ,tfp_nreal);
  1556.   Tfp_addobj(@xround ,'ROUND' ,tfp_1real);
  1557.   Tfp_addobj(@xsgn   ,'SGN'   ,tfp_1real);
  1558. END; {of Tfp_Addmisc}
  1559.  
  1560. {---------------------------------------------------------}
  1561.  
  1562. PROCEDURE Tfp_addinvarchyper;
  1563.  
  1564. BEGIN
  1565.   Tfp_expand(15);
  1566.   Tfp_addobj(@xcsc    ,'CSC'    ,tfp_1real);
  1567.   Tfp_addobj(@xsec    ,'SEC'    ,tfp_1real);
  1568.   Tfp_addobj(@xcot    ,'COT'    ,tfp_1real);
  1569.  
  1570.   Tfp_addobj(@xsinh   ,'SINH'   ,tfp_1real);
  1571.   Tfp_addobj(@xcosh   ,'COSH'   ,tfp_1real);
  1572.   Tfp_addobj(@xtanh   ,'TANH'   ,tfp_1real);
  1573.  
  1574.   Tfp_addobj(@xcsch   ,'CSCH'   ,tfp_1real);
  1575.   Tfp_addobj(@xsech   ,'SECH'   ,tfp_1real);
  1576.   Tfp_addobj(@xcoth   ,'COTH'   ,tfp_1real);
  1577.  
  1578.   Tfp_addobj(@xarcsinh,'ARCSINH',tfp_1real);
  1579.   Tfp_addobj(@xarccosh,'ARCCOSH',tfp_1real);
  1580.   Tfp_addobj(@xarctanh,'ARCTANH',tfp_1real);
  1581.  
  1582.   Tfp_addobj(@xarccsch,'ARCCSCH',tfp_1real);
  1583.   Tfp_addobj(@xarcsech,'ARCSECH',tfp_1real);
  1584.   Tfp_addobj(@xarccoth,'ARCCOTH',tfp_1real);
  1585. End; {of Add_invandhyper}
  1586.  
  1587. {---------------------------------------------------------}
  1588.  
  1589. PROCEDURE Tfp_addall;
  1590.  
  1591. BEGIN
  1592.   Tfp_addgonio;
  1593.   Tfp_addlogic;
  1594.   Tfp_addmath;
  1595.   Tfp_addmisc;
  1596.   Tfp_addinvarchyper;
  1597. END; {of Tfp_addall}
  1598.  
  1599. {---------------------------------------------------------}
  1600.  
  1601. BEGIN
  1602. {----Module Init}
  1603.   tfp_erpos :=0;
  1604.   tfp_ernr  :=0;
  1605.   fiesiz:=0;
  1606.   maxfie:=0;
  1607.   fiearr:=NIL;
  1608. END.
  1609.